﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Marmat.Foundation;
using Marmat.Forms.Skin;
using DevExpress.XtraPrinting.Native;

namespace Marmat.Template.WinForm
{
    internal class PermissionFormUserControl : Marmat.Forms.Skin.ScrollControl
    {
        /// <summary>
        /// 获取已经存在的用户集合。
        /// </summary>
        internal List<IUserEntity> users = new List<IUserEntity>();
        private Dictionary<IUserEntity, Rectangle> userRectangleCollection = new Dictionary<IUserEntity, Rectangle>();
        private Dictionary<IUserEntity, Rectangle> deleteRectangleCollection = new Dictionary<IUserEntity, Rectangle>();
        private IUserEntity mouseMoveItem;
        private Rectangle empty_Rectangle;
        private bool is_empty_Rectangle;
        private Point mousePosition;

        /// <summary>
        /// 点击添加用户时执行。
        /// </summary>
        public event EventHandler AddUsering;

        /// <summary>
        /// 点击删除用户时执行。
        /// </summary>
        public event EventHandler<IUserEntity> DeleteUsering;

        public PermissionFormUserControl()
        {
            SetStyle(ControlStyles.Selectable, true);
            SetStyle(ControlStyles.ResizeRedraw, true); //尺寸变化后绘制
            SetStyle(ControlStyles.Opaque, false); //改善绘图质量
            SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.DoubleBuffer, true);
        }

        public void AddRange(IEnumerable<IUserEntity> users)
        {
            this.users.AddRange(users);
            this.Invalidate();
        }

        public void Remove(IUserEntity user)
        {
            this.users.Remove(user);
            this.Invalidate();
        }


        public void SetUserCollection(IEnumerable<IUserEntity> users)
        {
            this.users.Clear();
            if (users is not null)
                this.users.AddRange(users);
            this.Invalidate();
        }

        public void Clear()
        {
            this.mouseMoveItem = null;
            this.users.Clear();
            this.Invalidate();
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            int columnIndex = 0;
            int itemWidth = 240;
            int itemHeight = 76;
            int interval = 9;
            int left = interval * 2;
            int top = interval * 2;

            userRectangleCollection.Clear();
            deleteRectangleCollection.Clear();
            List<object> collection = new List<object>(this.users);
            collection.Add("empty");
            foreach (var item in collection)
            {
                if (columnIndex > 0 && left + itemWidth + interval * 2 > this.Width)
                {
                    top += itemHeight + interval * 2;
                    columnIndex = 0;
                }
                if (columnIndex == 0)
                    left = interval;
                left += interval;
                columnIndex++;
                Rectangle rectangle = new Rectangle(left, top, itemWidth - 1, itemHeight - 1);
                left += rectangle.Width + interval;

                var path = rectangle.GetRoundPath(3);
                using SolidBrush brush = new SolidBrush(Color.FromArgb(247, 249, 251));
                e.Graphics.FillPath(brush, path);
                if (this.mouseMoveItem == item || (Equals(item, "empty") && empty_Rectangle.Contains(mousePosition)))
                {
                    using Pen pen = new Pen(Color.Gray);
                    pen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
                    e.Graphics.DrawPath(pen, path);
                    if (this.mouseMoveItem == item && item is IUserEntity t_user)
                    {
                        Image img = Properties.Resources.permissionForm_delete_icon;
                        Rectangle delete_rect = new Rectangle(rectangle.Right - img.Width - 6, rectangle.Top - img.Height / 2, img.Width, img.Height);
                        e.Graphics.DrawImage(img, delete_rect);
                        deleteRectangleCollection[t_user] = delete_rect;
                    }
                }
                if (item is IUserEntity user)
                {
                    userRectangleCollection[user] = rectangle;
                    Image img = Properties.Resources.default_portrait;
                    e.Graphics.DrawImage(Properties.Resources.default_portrait, rectangle.X + interval * 2, rectangle.Y + (rectangle.Height - img.Height) / 2);
                    rectangle = new Rectangle(rectangle.X + img.Width + interval * 3, rectangle.Y, rectangle.Width - (img.Width + interval * 3), rectangle.Height);
                    TextRenderer.DrawText(e.Graphics, user.NickName ?? user.UserID, this.Font, rectangle, this.ForeColor, Color.Transparent, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
                }
                else if (Equals(item, "empty"))
                {
                    empty_Rectangle = rectangle;
                    TextRenderer.DrawText(e.Graphics, "+  添加成员", this.Font, rectangle, Color.FromArgb(16, 127, 255), Color.Transparent, TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
                }
            }
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);
            mousePosition = e.Location;
            var item1 = this.userRectangleCollection.FirstOrDefault(x => x.Value.Contains(e.Location)).Key;
            var item2 = this.deleteRectangleCollection.FirstOrDefault(x => x.Value.Contains(e.Location)).Key;
            if (this.mouseMoveItem != (item1 ?? item2))
            {
                this.mouseMoveItem = item1 ?? item2;
                this.Invalidate();
            }
            this.Cursor = item2 is not null ? Cursors.Hand : Cursors.Default;

            var tmp_is_empty_Rectangle = this.empty_Rectangle.Contains(e.Location);
            if (tmp_is_empty_Rectangle != is_empty_Rectangle)
            {
                is_empty_Rectangle = tmp_is_empty_Rectangle;
                this.Cursor = tmp_is_empty_Rectangle ? Cursors.Hand : Cursors.Default;
                this.Invalidate();
            }
        }

        protected override void OnLeave(EventArgs e)
        {
            base.OnLeave(e);
            mousePosition = default;
            this.mouseMoveItem = null;
            this.Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            if (empty_Rectangle.Contains(e.Location))
                this.AddUsering?.Invoke(this, EventArgs.Empty);
            else
            {
                var item = deleteRectangleCollection.FirstOrDefault(x => x.Value.Contains(e.Location));
                if (item.Key is not null)
                {
                    this.DeleteUsering?.Invoke(this, item.Key);
                }
            }
        }
    }
}
